package fun.tan90.trace;

import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;

public class ThresholdFilter {

    private final AtomicBoolean init = new AtomicBoolean(false);

    private String filterType;

    private Double currentValue;

    private final double valThreshold;

    private final int countThreshold;

    private final AtomicInteger countThresholdLauncher;

    public ThresholdFilter(Double valThreshold, int countThreshold) {
        this.valThreshold = valThreshold;
        this.countThreshold = countThreshold;
        this.countThresholdLauncher = new AtomicInteger(this.countThreshold);
    }

    public void filterVal(Double newVal, BiConsumer<String, Double> biConsumer) {
        filterVal(newVal, false, biConsumer);
    }


    public void filterVal(Double newVal, boolean heading, BiConsumer<String, Double> biConsumer) {
        if (init.compareAndSet(false, true)) {
            this.currentValue = newVal;
            this.filterType = "初始化赋值";
        } else {
            if (Objects.nonNull(newVal)) {
                double diff = Math.abs(newVal - Optional.ofNullable(currentValue).orElse(0.D));
                if (heading) {
                    diff = diff > 180 ? 360 - diff : diff;
                }
                if (diff >= valThreshold) {
                    this.countThresholdLauncher.set(this.countThreshold);
                    this.currentValue = newVal;
                    this.filterType = "阈值赋值";
                } else {
                    if (this.countThresholdLauncher.decrementAndGet() == 0) {
                        this.countThresholdLauncher.set(this.countThreshold);
                        this.currentValue = newVal;
                        this.filterType = "数据量赋值";
                    }
                }
            } else {
                if (this.countThresholdLauncher.decrementAndGet() == 0) {
                    this.countThresholdLauncher.set(this.countThreshold);
                    this.currentValue = null;
                    this.filterType = "数据量赋值";
                }
            }
        }
        biConsumer.accept(this.filterType, this.currentValue);
    }
}
